package me.ingxin.android.activitylauncher

import android.app.Activity
import android.content.Intent
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityOptionsCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity

private const val TAG = "LaunchFragment"

@JvmOverloads
fun <I, O> FragmentActivity.launchActivityForResult(
    input: I?,
    contract: ActivityResultContract<I, O>,
    options: ActivityOptionsCompat? = null,
    callback: ActivityResultCallback<O>
) {
    val holder = LaunchFragment<I, O>()
    holder.attach(input, callback, contract, options)
    supportFragmentManager.beginTransaction()
        .add(holder, TAG)
        .commitAllowingStateLoss()
}

@JvmOverloads
fun <I, O> Fragment.launchActivityForResult(
    input: I?,
    contract: ActivityResultContract<I, O>,
    options: ActivityOptionsCompat? = null,
    callback: ActivityResultCallback<O>,
) {
    val holder = LaunchFragment<I, O>()
    holder.attach(input, callback, contract, options)
    activity?.supportFragmentManager?.beginTransaction()
        ?.add(holder, TAG)
        ?.commitAllowingStateLoss()
}

@JvmOverloads
fun FragmentActivity.launchActivityForResult(
    intent: Intent,
    options: ActivityOptionsCompat? = null,
    callback: ActivityResultCallback<ActivityResult>
) {
    launchActivityForResult<Intent, ActivityResult>(
        intent,
        ActivityResultContracts.StartActivityForResult(),
        options,
        callback
    )
}

@JvmOverloads
fun FragmentActivity.launchActivityForResult(
    clazz: Class<out Activity>,
    options: ActivityOptionsCompat? = null,
    callback: ActivityResultCallback<ActivityResult>
) {
    launchActivityForResult<Intent, ActivityResult>(
        Intent(this, clazz),
        ActivityResultContracts.StartActivityForResult(),
        options,
        callback
    )
}

@JvmOverloads
fun Fragment.launchActivityForResult(
    intent: Intent,
    options: ActivityOptionsCompat? = null,
    callback: ActivityResultCallback<ActivityResult>
) {
    launchActivityForResult<Intent, ActivityResult>(
        intent,
        ActivityResultContracts.StartActivityForResult(),
        options,
        callback
    )
}

@JvmOverloads
fun Fragment.launchActivityForResult(
    clazz: Class<out Activity>,
    options: ActivityOptionsCompat? = null,
    callback: ActivityResultCallback<ActivityResult>
) {
    launchActivityForResult<Intent, ActivityResult>(
        Intent(activity, clazz),
        ActivityResultContracts.StartActivityForResult(),
        options,
        callback
    )
}